<template>
  <div>
    <!-- <button @click="login">登录</button>
    <button @click="logout">退出登录</button>
    <button @click="previewOutcall">外呼</button>
    <button @click="sipLink">接听</button>
    <button @click="refuse">拒接</button>
    <button @click="sipUnlink">挂断</button>
    <button @click="pause">置忙</button>
    <button @click="unpause">置闲</button> -->
    <!-- 客服状态 -->
    <div v-if="isHaveTianRunData" class="frame-quick-phoneServiceStatus">
      <!-- 状态图标 -->
      <span
        class="status-dot cursor-pointer iconfont icon-zaixiandingbu"
        @click="iconHandelClick"
      >
        <i
          class="dot"
          :style="{ 'background-color': currentStatusInfo.color }"
        ></i>
      </span>

      <el-popover placement="bottom" trigger="click">
        <span slot="reference">
          <!-- 当前状态 -->
          <span class="service-status-text cursor-pointer">{{
            currentStatusInfo.text
          }}</span>
        </span>

        <div class="customer-service-info">
          <div class="customer-service-top">
            <span>电话客服</span>
            <el-dropdown
              placement="bottom"
              trigger="hover"
              @command="handleCommand"
            >
              <div class="service-status-dropdown">
                <span
                  class="dot"
                  :style="{ 'background-color': currentStatusInfo.color }"
                ></span>
                {{ currentStatusInfo.text }}
                <i class="iconfont icon-triangle-down"></i>
              </div>

              <el-dropdown-menu slot="dropdown">
                <template v-for="(item, index) in statusList">
                  <el-dropdown-item :key="index" :command="item.code">
                    <span
                      class="dot"
                      :style="{
                        'background-color':
                          index === 1 ? item.color : item.color,
                      }"
                    ></span>
                    {{ item.action }}
                  </el-dropdown-item>
                </template>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
          <div class="customer-service-bottom">
            <span>编号{{ currentAgent.cno || '' }}</span>
          </div>
        </div>
      </el-popover>
    </div>

    <!-- start 通话弹窗 -->
    <div v-if="showCallCenter && callCenterData" class="call-center-box">
      <p class="customer-name">
        {{ callCenterData.linkmanName || '未知联系人' }}
      </p>

      <div class="divider"></div>

      <div class="call-ripple">
        <div class="icon-ripple">
          <img :src="phoneImage" />
          <div class="ripple1"></div>
          <div class="ripple2"></div>
        </div>
      </div>

      <p style="margin-top: 10px; font-size: 26px">
        {{ callStatusDisplayText }}：
        {{ callCenterData.phone }}
      </p>

      <p v-if="callAreaName">
        {{ callAreaName }}
      </p>

      <div class="flex-x call-opt-btn">
        <!-- start 呼入 -->
        <template v-if="callCenterData.isCallIn">
          <el-button type="primary" @click="sipLink"> 接听 </el-button>
          <el-button type="danger" @click="refuse"> 拒接 </el-button>
        </template>
        <!-- end 呼入 -->

        <!-- start 呼出 -->
        <template v-if="callCenterData.isCallOut">
          <el-button type="danger" @click="sipUnlink"> 取消 </el-button>
        </template>
        <!-- end 呼出 -->
      </div>
    </div>
    <!-- end 通话弹窗 -->
  </div>
</template>

<script>
/* api */
import * as CallCenterApi from '@src/api/CallCenterApi';
/** util */
import { openAccurateTab } from '@src/util/platform';
import { PageRoutesTypeEnum } from '@model/enum/PageRoutesEnum';
import Log from '@src/util/log.ts';
import { loadScript } from '@src/util/dom';
/* service */
import CallCenterService from '@service/CallCenterService';
/* enum */
import { CallCenterTypeEnum } from '@model/enum/CallCenterEnum';

import { getOssUrl } from '@src/util/assets'
const phoneImage = getOssUrl('/phone.png')
export default {
  name: 'CallCenterTianRun',
  data() {
    return {
      phoneImage,
      // 是否含有天润呼叫中心数据
      isHaveTianRunData: false,
      // 当前座席信息
      currentAgent: {
        code: 'OFFLINE', //座席状态  OFFLINE:离线  IDLE:空闲 PAUSE:忙碌
      },
      callCenterOptions: {
        type: null,
        companyId: null,
        clientId: null,
        clientSecret: null,
        agentId: null,
        token: null,
      },
      callCenterData: {
        // 联系人名称
        name: '',
        // 联系人电话
        phone: '',
        // 是否为呼入
        isCallIn: false,
        // 是否为呼出
        isCallOut: false,
        // 号码归属地-省
        numberProvince: '',
        // 号码归属地-市
        numberCity: '',
        // 通话ID
        callId: '',
        // 是否正在通话中
        isOnCall: false,
        // 是否显示当前通话
        isShowCurrentCall: false,
      },
      showCallCenter: false, //是否显示通话弹窗
      phoneStatusMap: {
        IDLE: {
          color: '#00C853',
          text: '工作中',
        },
        OFFLINE: {
          color: '#D4D4D4',
          text: '休息中',
        },
        PAUSE: {
          color: '#FFAE00',
          text: '忙碌中',
        },
      },
    };
  },
  computed: {
    callStatusDisplayText() {
      if (this.callCenterData?.isCallIn) return '呼入';
      if (this.callCenterData?.isCallOut) return '呼出';
      return '';
    },
    // 当前电话客服信息
    currentStatusInfo() {
      return this.phoneStatusMap[this.currentAgent.code] || {};
    },
    // 电话地址
    callAreaName() {
      return (
        this.callCenterData.numberProvince + this.callCenterData.numberCity
      );
    },
    // 状态切换列表
    statusList() {
      let state = this.currentAgent.code;
      if (state == 'OFFLINE') {
        return [
          {
            code: 'IDLE',
            statusDescription: '空闲',
            action: '开始工作',
            color: '#00C853',
          },
        ];
      }

      if (state == 'PAUSE') {
        return [
          {
            code: 'UNPAUSE',
            statusDescription: '空闲',
            action: '开始工作',
            color: '#00C853',
          },
          {
            code: 'OFFLINE',
            statusDescription: '离线',
            action: '开始休息',
            color: '#D4D4D4',
          },
        ];
      }

      if (state == 'IDLE') {
        return [
          {
            code: 'OFFLINE',
            statusDescription: '离线',
            action: '开始休息',
            color: '#D4D4D4',
          },
        ];
      }

      return [
        {
          code: 'OFFLINE',
          statusDescription: '离线',
          action: '开始休息',
          color: '#D4D4D4',
        },
      ];
    },
  },
  mounted() {
    CallCenterService.setIsCallCenterTianRun(true);
    loadScript('https://ws-bj.clink.cn/clink-client.js?id=gdcpz-demo').then(res=>{
      this.ClinkAgentInitialize();
    }).catch(error=>{
      console.log(error,'天润sdk加载失败')
    })
  },
  methods: {
    handleState(data) {
      console.log(data);
      switch (data.code) {
        // 座席离线
        case 'OFFLINE': {
          console.log('OFFLINE-离线');
          this.setCurrentAgent(data);
          break;
        }
        // 座席空闲
        case 'IDLE': {
          console.log('IDLE-空闲');
          this.callCenterData.isOnCall = false;
          this.callCenterData.isShowCurrentCall = false;
          this.showCallCenter = false;
          if (data.action != 'idle') {
            // 客服未打通主动挂断电话、座席拒接呼入电话、客户呼入途中挂断电话
            this.goCallCenterWorkbench();
          }
          this.setCurrentAgent(data);
          break;
        }
        // 座席忙碌
        case 'PAUSE': {
          console.log('PAUSE-忙碌');
          this.setCurrentAgent(data);
          break;
        }
        // 呼叫中
        case 'CALLING': {
          console.log('呼叫中');
          break;
        }
        // 响铃中
        case 'RINGING': {
          switch (data.action) {
            //呼入座席响铃
            case 'ringingIb': {
              console.log('呼入座席响铃');
              break;
            }
            //外呼座席响铃
            case 'ringingAgentOb': {
              console.log('外呼座席响铃');
              break;
            }
          }
          break;
        }
        // 通话中
        case 'BUSY': {
          switch (data.action) {
            //外呼座席接通，呼叫客户中
            case 'busyAgentOb': {
              console.log('外呼座席接通，呼叫客户中');
              break;
            }
            //外呼客户响铃
            case 'ringingCustomerOb': {
              console.log('外呼客户响铃');
              break;
            }

            //外呼客户接听
            case 'busyOb': {
              console.log('外呼客户接听');
              this.callCenterData.isOnCall = true;
              this.callCenterData.isShowCurrentCall = true;
              this.goCallCenterWorkbench();
              break;
            }

            // 呼入接听
            case 'busyIb': {
              console.log('呼入接听');
              this.callCenterData.isOnCall = true;
              this.callCenterData.isShowCurrentCall = true;
              this.goCallCenterWorkbench();
              break;
            }

            default: {
            }
          }
          break;
        }
        //整理开始（座席/客户挂断）
        case 'WRAPUP': {
          console.log('座席/客户挂断');
          this.callCenterData.isOnCall = false;
          this.callCenterData.isShowCurrentCall = false;
          this.goCallCenterWorkbench();
          break;
        }
      }
    },
    handleRinging(data) {
      console.log(data, 11111);
      if (data.callType == 4) {
        // 呼出电话
        this.changeCallCenterDataIsCall(false, true);
      } else if (data.callType == 1) {
        // 呼入电话
        this.changeCallCenterDataIsCall(true, false);
      }

      this.setCallDataNumberAndId(data);
      // 查询客户详情
      this.fetchLinkMenInfo(data.customerNumber);
    },
    // 监听短线
    breakLineInfo(data) {
      this.logout();
      return this.$notify({
        title: '提示',
        message: '呼叫中心坐席已断线,请重新登录',
        type: 'error',
      });
    },
    /** 登录回调 */
    callbackLogin(data) {
      if (data.code != 0) {
        return this.$notify({
          title: '呼叫中心座席签入失败',
          message: data.msg,
          type: 'error',
        });
      }
    },
    /**登录退出回调 */
    callbackLogout(data) {
      this.isOnCall = false;
      this.showCallCenter = false;
    },
    /**
     * 监听座席操作以及事件
     */
    initTianRun() {
      // 监听事件
      let isOpenTianRunDebug = sessionStorage.getItem('tianRunDebug') == 1;
      ClinkAgent.setup({ sipPhone: true, debug: isOpenTianRunDebug }, () => {
        console.log('ClinkAgent.setup OK!');

        /** 状态事件 */
        ClinkAgent.registerListener(
          ClinkAgent.EventType.STATUS,
          this.handleState
        ); //当前座席状态

        ClinkAgent.registerListener(
          ClinkAgent.EventType.PREVIEW_OUTCALL_START,
          this.handleState
        ); // 预览外呼呼叫

        ClinkAgent.registerListener(
          ClinkAgent.EventType.PREVIEW_OUTCALL_RINGING,
          this.handleState
        ); //预览外呼客户响铃

        ClinkAgent.registerListener(
          ClinkAgent.EventType.PREVIEW_OUTCALL_BRIDGE,
          this.handleState
        ); //预览外呼客户接听

        ClinkAgent.registerListener(
          ClinkAgent.EventType.RINGING,
          this.handleRinging
        ); // 弹屏、响铃

        ClinkAgent.registerListener(
          ClinkAgent.EventType.BREAK_LINE,
          this.breakLineInfo
        ); //短线重连

        ClinkAgent.registerListener(ClinkAgent.EventType.KICKOUT, data => {
          this.currentAgent.code = 'OFFLINE';
          this.$notify({
            title: '提示',
            message: '呼叫中心座席被踢下线,请联系管理员',
            type: 'error',
          });
        });

        ClinkAgent.registerListener(
          ClinkAgent.EventType.UNREACHABLE_AUTO_PAUSE,
          data => {
            // console.log('检测到话机不可达：' + JSON.stringify(data));
          }
        );

        // 座席登录操作回调
        ClinkAgent.registerCallback(
          ClinkAgent.ResponseType.LOGIN,
          this.callbackLogin
        );

        // 坐席签出回调
        ClinkAgent.registerCallback(
          ClinkAgent.ResponseType.LOGOUT,
          this.callbackLogout
        );

        ClinkAgent.registerListener(
          ClinkAgent.EventType.SIP_DISCONNECTED,
          data => {
            if (data.code != 0) {
              console.log(data, '软电话断线');
              this.logout();
              // this.$notify({
              //   title: '提示',
              //   message: '软电话已断线',
              //   type: 'error',
              // });
            }
          }
        ); // 软电话断线

        ClinkAgent.registerListener(
          ClinkAgent.EventType.SIP_CONNECTED,
          data => {
            console.log(data, '软电话连接');
            data => {
              if (data.code != 0) {
                this.logout();
                this.$notify({
                  title: '提示',
                  message: '软电话连接失败，请重新登录',
                  type: 'error',
                });
              }
            };
          }
        ); // 软电话连接

        ClinkAgent.registerListener(
          ClinkAgent.EventType.SIP_REGISTERED,
          data => {
            console.log(data, '软电话注册');
            if (data.code != 0) {
              this.logout();
              this.$notify({
                title: '提示',
                message: '软电话注册失败，请重新登录',
                type: 'error',
              });
            }
          }
        ); // 软电话连接
      });
    },

    async ClinkAgentInitialize() {
      if (!ClinkAgent) return console.log('ClinkAgent未定义');
      // 1. 首先获取呼叫中心数据
      await this.fetchCallCenterInfo();
      // 2,不含有天润呼叫中心数据，则不初始化
      if (!this.isHaveTianRunData) return;

      this.initTianRun();

      window.getTianRunCallCenterData = this.outSideGetCallCenterData;

      window.previewOutcall = this.previewOutcall;

      window.onbeforeunload = () => {
        this.logout();
      };
    },

    //座席登录
    login() {
      let { token, companyId } = this.callCenterOptions;
      const params = {
        identifier: companyId,
        agentToken: token,
        agentTokenLogin: 1,
        bindTel: '',
        bindType: 3,
        loginStatus: 1,
      };
      ClinkAgent.login(params);
    },

    //座席退出
    logout() {
      const params = {
        logoutMode: 1,
        removeBinding: 0,
      };
      ClinkAgent.logout(params);
    },

    //外呼
    previewOutcall(tel) {
      if (this.currentAgent.code != 'IDLE') {
        this.$notify({
          title: '提示',
          message: '呼出失败：座席未登录',
          type: 'error',
        });
        return
      }
      const params = {
        tel,
      };
      ClinkAgent.previewOutcall(params);
    },
    // 座席拒接电话
    refuse() {
      ClinkAgent.refuse();
    },
    // 座席挂断电话
    sipUnlink() {
      ClinkAgent.sipUnlink();
    },
    // 座席接听电话
    sipLink() {
      ClinkAgent.sipLink();
    },
    // 座席置忙
    pause() {
      ClinkAgent.pause({ pauseType: 1 });
    },
    // 座席置闲
    unpause() {
      ClinkAgent.unpause();
    },
    /**
     * @description 更改呼入呼出状态
     * @param {Boolean} isCallIn 是否为呼入
     * @param {Boolean} isCallOut 是否为呼出
     * @returns {void}
     */
    changeCallCenterDataIsCall(isCallIn, isCallOut) {
      this.callCenterData.isCallIn = isCallIn;
      this.callCenterData.isCallOut = isCallOut;
    },
    /**
     * 跳转呼叫中心工作台页面
     */
    goCallCenterWorkbench() {
      this.showCallCenter = false;

      openAccurateTab({
        type: PageRoutesTypeEnum.PageSecurityCallcenterWorkbench,
        reload: true,
      });
    },

    iconHandelClick() {
      this.goCallCenterWorkbench();
    },

    handleCommand(command) {
      switch (command) {
        case 'IDLE': {
          this.login();
          break;
        }
        case 'OFFLINE': {
          this.logout();
          break;
        }
        case 'UNPAUSE': {
          this.unpause();
          break;
        }
      }
    },

    setCallDataNumberAndId(data = {}) {
      this.callCenterData.numberProvince = data.customerProvince;
      this.callCenterData.numberCity = data.customerCity;
      this.callCenterData.phone = data.customerNumber;
      this.callCenterData.callId = '-1'; // 新电话拿不到数据库id，-1用来判断是否用做当前通话信息
      this.callCenterData.callType = data.callType;
    },

    outSideGetCallCenterData() {
      return this.callCenterData;
    },
    // 查询是否有呼叫中心数据
    async fetchCallCenterInfo() {
      try {
        const data = await CallCenterApi.getCallCenterAccountInfoUpdate();
        const isSuccess = data?.success;
        const result = data?.result || {};

        const isHaveTianRunData = result?.[CallCenterTypeEnum.TianRun];

        if (isSuccess && isHaveTianRunData) {
          this.isHaveTianRunData = true;
          this.callCenterOptions = Object.assign(
            {},
            this.callCenterOptions,
            result[CallCenterTypeEnum.TianRun]
          );
          localStorage.setItem('call_center_agent', 1); // 天润呼叫中心 有数据说明就是绑定了坐席
        }
      } catch (error) {
        Log.error(error, this.fetchCallCenterInfo.name);
      }
    },
    /**
     * @description 获取联系人信息
     * @param {String} phone 呼入/呼出 电话号码
     */
    async fetchLinkMenInfo(phone) {
      try {
        const res = await CallCenterApi.agentGetLinkmanInfo({ phone });
        if (res.success) {
          this.callCenterData = Object.assign(
            {},
            this.callCenterData,
            res.result || {linkmanName:'',name:''}
          );
        }
      } catch (error) {
        Log.error(error, this.fetchLinkMenInfo.name);
      } finally {
        this.showCallCenter = true;
      }
    },
    setCurrentAgent(data) {
      this.currentAgent = data;
    },
  },
};
</script>

<style scoped lang="scss">
.frame-quick-phoneServiceStatus {
  font-size: 14px;
  padding: 0 0px;
  .status-text {
    color: #8c8c8c;
  }
  .icon-dianhua1 {
    color: #8c8c8c;
    cursor: pointer;
  }
}
.call-center-box {
  position: fixed;
  width: 400px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transform-origin: center top;
  z-index: 2001;
  background: #fff;
  border: 1px solid #ebeef5;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  .customer-name {
    color: $text-color-main;
    font-size: 24px;
    margin: 14px 0;
    color: #333;
  }
  p > span {
    color: #ed3f14;
  }

  .divider {
    height: 1px;
    width: 100%;
    background: #f5f5f5;
  }

  .call-ripple {
    position: relative;
    width: 90px;
    height: 90px;
    .icon-ripple {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      img {
        width: 48px;
        height: 48px;
        border-radius: 50%;
      }
      div[class^='ripple'] {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 48px;
        height: 48px;
        box-shadow: 0 0 1.5px $color-primary;
        border-radius: 50%;
        animation: ripple 1.2s linear infinite;
      }
      div.ripple2 {
        animation-delay: 0.4s;
      }
    }
  }

  .call-in,
  .call-out {
    width: 100%;
    display: flex;
    // flex-direction: column;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: 0 10px;
    a {
      width: 50%;
      text-decoration: underline;
      color: $color-primary-light-6;
      padding: 0 10px;
      cursor: pointer;
      margin-bottom: 10px;
      font-size: 16px;
      &:nth-child(odd) {
        text-align: right;
      }
      &:nth-child(even) {
        text-align: left;
      }
    }
  }

  .call-opt-btn {
    margin: 10px 0 20px 0;
  }

  .last {
    width: 100%;
    background: #fb602c;
    height: 26px;
    padding: 4px 0;
    margin-bottom: 0;
    color: #fff;
    opacity: 0.8;
    text-align: center;
  }

  @keyframes ripple {
    0% {
    }
    50% {
      width: 70px;
      height: 70px;
      opacity: 1;
    }
    100% {
      width: 90px;
      height: 90px;
      opacity: 0;
    }
  }
}
</style>
<style lang="scss">
.custom-popper {
  z-index: 99 !important;
}
.call-transfer {
  .icon-shezhi {
    color: rgb(140, 140, 140) !important;
    font-size: 14px;
  }
}
.call-transfer-main {
  color: rgb(140, 140, 140);
  .desc {
    margin-bottom: 10px;
  }
  .el-input-group__append {
    border: 1px solid #e0e1e2 !important;
    border-radius: 0 !important;
    padding: 0;
    .subBtn {
      width: 100%;
      text-align: center;
      padding: 0 15px;
      cursor: pointer;
    }
  }
}
</style>

<style lang="scss">
.frame-quick-phoneServiceStatus {
  .el-dropdown-link {
    cursor: pointer;
  }
}
.call-center-box {
  .el-button--danger:hover,
  .el-button--danger:focus {
    background: #f78989;
    border-color: #f78989;
    color: #fff;
  }
}

.agent-panel-popper-content {
  border-radius: 6px;
  height: 402px;
  padding-top: 12px;
}

.agent-panel-popper-content-state {
  user-select: none;

  border: 0;
  /* background-color: #EFF3FA;
  color: #6d7894; */
  border-radius: 2px;
  font-size: 14px;
  font-weight: 400;
  width: 100%;
  height: 32px;

  display: flex;
  align-items: center;
  justify-content: center;

  cursor: pointer;

  .el-dropdown-link {
    i {
      color: #9c9c9c;
      font-size: 12px;
    }
  }
}

.agent-panel-popper-content-state-header {
  display: flex;
  width: 100%;
  padding-left: 20px;
  padding-right: 20px;
  .el-select {
    width: 100%;
  }
  i {
    width: 30px;
    height: 30px;
    margin-left: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.agent-panel-popper-content-state-dot {
  display: inline-block;
  border-radius: 4px;
  width: 8px;
  height: 8px;
}

.agent-panel-popper-content-offline {
  width: 262px;
  height: 364px;

  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}

.callcenter-reset-container {
  z-index: 4000 !important;
  .base-modal-body {
    padding: 20px;
    line-height: 30px;
  }
}
</style>
